package com.pan.net;

import com.pan.entity.transmit.Packet;

import java.io.*;
import java.net.Socket;
import java.util.concurrent.locks.ReentrantLock;

public class Communication {

    private Socket socket;

    private ReentrantLock readLock;

    private ReentrantLock writeLock;

    private ObjectInputStream objectInputStream;

    private ObjectOutputStream objectOutputStream;

    private InputStream inputStream;

    private OutputStream outputStream;


    public Communication(Socket socket) throws IOException {
        this.socket = socket;

        readLock = new ReentrantLock();
        inputStream = socket.getInputStream();
//        objectInputStream = new ObjectInputStream(inputStream);

        writeLock = new ReentrantLock();
        outputStream = socket.getOutputStream();
        objectOutputStream = new ObjectOutputStream(outputStream);
    }

    public boolean checkSocket(){
        return socket.isConnected();
    }


    public void send(Packet sendPacket){

        writeLock.lock();
        try {
            objectOutputStream.writeObject(sendPacket);
            objectOutputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        writeLock.unlock();
    }

    public Packet receive()  {
        Packet receive ;
        readLock.lock();
        try {
            objectInputStream = objectInputStream ==null?
                    new ObjectInputStream(inputStream):objectInputStream;
            receive = (Packet) objectInputStream.readObject();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        readLock.unlock();
        return receive;
    }



    public void close(){
        try {
            writeLock.lock();
            objectOutputStream.close();
            outputStream.close();
            writeLock.unlock();

            readLock.lock();
            objectInputStream.close();
            inputStream.close();
            readLock.unlock();

            socket.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
